package org.muninn.niagara.services;

import javax.baja.status.BStatusString;
import javax.baja.sys.Action;
import javax.baja.sys.BIcon;
import javax.baja.sys.Clock;
import javax.baja.sys.Flags;
import javax.baja.sys.Property;
import javax.baja.sys.Sys;
import javax.baja.sys.Type;

import org.muninn.niagara.structures.BJaceTree;

public class BParamDownloadService extends BMuninnService
{
  /** Allow service to be executed (automatically set to false every time service is executed to prevent overworking the processor) **/
  public static final Property enabled = newProperty(0, false);
  public void setEnabled(boolean v) { setBoolean(enabled, v); }
  public boolean getEnabled() { return getBoolean(enabled); }
  
  /** Execute tests in verbose mode */
  public static final Property report = newProperty(0, false);
  public void setReport(boolean v) { setBoolean(report, v); }
  public boolean getReport() { return getBoolean(report); }

  /** Path to the XML file */
  public static final Property filePath = newProperty(0, "C:\\WEBStation\\stations\\Station\\xml\\ParamFile.xml");
  public void setFilePath(String v) { setString(filePath, v); }
  public String getFilePath() { return getString(filePath); }
  
  /** Path to the folder of error logs */
  public static final Property logPath = newProperty(0, "C:\\WEBStation\\stations\\Station\\logs\\");
  public void setLogPath(String v) { setString(logPath, v); }
  public String getLogPath() { return getString(logPath); }
  
  /** Test mode to be executed */
  public static final Property modeNumber = newProperty(0, 1);
  public void setModeNumber(int v) { setInt(modeNumber, v); }
  public int getModeNumber() { return getInt(modeNumber); } 
  
  /** Latency tolerance (in seconds) */
  public static final Property tolerance = newProperty(0, 1.0);
  public void setTolerance(double v) { setDouble(tolerance, v); }
  public double getTolerance() { return getDouble(tolerance); }
  
  /** Number of errors detected in log */
  public static final Property problems = newProperty(Flags.READONLY, 0);
  public void setProblems(int v) { setInt(problems, v); }
  public int getProblems() { return getInt(problems); }
  
  /** Hidden property to generate errors-only output */
  public static final Property stream = newProperty(Flags.READONLY | Flags.HIDDEN, new BStatusString());
  public void setStream(BStatusString v) { set("stream", v); }
  public BStatusString getStream() { return (BStatusString) get("stream"); }
  
  private static BParamDownloadService INSTANCE = null;

  private static String file;
  private static String log;
  private static double tol;
  private static int mode;
  private static boolean verbose;

  public static final Action execute = newAction(Flags.ASYNC|Flags.DEFAULT_ON_CLONE, null);
  public void execute() { invoke(execute, null, null); }
  
  /**
   * Main operation method 
   * @throws Exception
   */
  public void doExecute() throws Exception
  {
    if (!getEnabled())
      return;
    
    file = getFilePath();
    log = getLogPath();
    tol = getTolerance();
    mode = getModeNumber();
    verbose = getReport();
    String outStream = "";
    
    setEnabled(false);
    
    BJaceTree system = new BJaceTree(file, verbose);

    if (system.isBuilt())
    {
      for (int i = 0; i < system.size(); i++)
      {
        boolean connect = system.startSessionOnIP(i);
        
        if (connect)
        {
          system.getIP(i).executeModes(mode);

          long time = Clock.millis();
          while ((Clock.millis() - time) < (tol * 1000)) {}
          
          system.getIP(i).checkModes(mode);

          system.stopCurrentSession();
        }

        else
          System.out.println("IP connect failed, exiting...");
      }
    }
    
    else
      System.out.println("Tree build failed, exiting...");
    
    if (verbose)
      outStream = system.makeLog(log);
    
    getStream().setValue(outStream);
    setProblems(outStream.split("\\*\\*\\*").length - 1);
  }
  
  public BIcon getIcon() { return icon; }
  private static final BIcon icon = BIcon.make("local:|module://muninn/org/muninn/niagara/graphics/MuninnGroup.PNG");

  public static final Type TYPE = Sys.loadType(BParamDownloadService.class);
  public Type[] getServiceTypes() { return new Type[] { TYPE }; }
  public Type getType() { return TYPE; }

  public final synchronized void serviceStarted() throws Exception { INSTANCE = this; }

  public final synchronized void serviceStopped() throws Exception { INSTANCE = null; }
  
  public static final BParamDownloadService getInstance() { return INSTANCE; }
}
